package com.radar.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.io.FileUtil;
import com.radar.common.DateConstants;
import com.radar.model.ResultBody;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import java.io.File;
import java.io.IOException;
import java.util.*;

@Api(tags = "1.0 文件系统接口")
@RestController
@RequestMapping("fileSystem")
@Slf4j
public class FileSystemController {

    @ApiOperation("1.0.获取文件列表")
    @GetMapping("/ls")
    @ApiImplicitParam(name = "file", value = "文件路径", defaultValue = "/Users/xx/code", example = "/Users/xx/code", paramType = "query", required = true, dataType = "String")
    public ResultBody ls(@ApiIgnore @RequestParam String file) {
        File[] ls;
        List<Map> list = new ArrayList<>();
        File fi = new File(file);
        try {
            if(!FileUtil.exist(fi)){
                return ResultBody.failed();
            }
            ls = FileUtil.ls(fi.getAbsolutePath());
            Arrays.asList(ls).forEach(f -> {
                Map<String, Object> map = new HashMap<>();
                map.put("name", f.getName());
                map.put("isDirectory", f.isDirectory());
                map.put("isHidden", f.isHidden());
                if (f.isFile()) {
                    long len = f.length();
                    if (len <= 1024) {
                        map.put("size", len + " B");
                    } else if (len > (1024 * 1024 * 1024)) {
                        map.put("size", String.format("%.2f GB", (len / 1024.0 / 1024.0 / 1024.0)));
                    } else if (len > (1024 * 1024)) {
                        map.put("size", String.format("%.2f MB", (len / 1024.0 / 1024.0)));
                    } else if (len > 1024) {
                        map.put("size", String.format("%.2f KB", (len / 1024.0)));
                    }
                }
                map.put("lastModified", f.lastModified());
                list.add(map);
            });
            try{
                list.stream().filter(i -> i.get("lastModified") != null).sorted((o1, o2) -> (long) o1.get("lastModified") < (long) o2.get("lastModified") ? -1 : 1);
            }catch (Exception e){
                log.error(ExceptionUtil.getMessage(e));
            }
            list.stream().filter(i -> i.get("lastModified") != null).forEach(i -> i.put("lastModified", DateUtil.format(new Date((long) i.get("lastModified")), DateConstants.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS)));
        } catch (Exception e) {
            log.error(ExceptionUtil.stacktraceToString(e));
            return ResultBody.failed();
        }
        return ResultBody.ok().data(list).put("path", fi.getAbsolutePath());
    }

    @ApiOperation("1.1.新建文件夹")
    @GetMapping("/mkdir")
    @ApiImplicitParam(name = "file", value = "文件路径", defaultValue = "/Users/xx/code/test", example = "/Users/xx/code", paramType = "query", required = true, dataType = "String")
    public ResultBody mkdir(@ApiIgnore @RequestParam String file) {
        return FileUtil.mkdir(file) != null ? ResultBody.ok() : ResultBody.failed();
    }

    @ApiOperation("1.2.删除文件以及文件夹")
    @GetMapping("/del")
    @ApiImplicitParam(name = "file", value = "文件路径", defaultValue = "/Users/xx/code/test", example = "/Users/xx/code", paramType = "query", required = true, dataType = "String")
    public ResultBody del(@ApiIgnore @RequestParam String file) {
        return FileUtil.del(file) ? ResultBody.ok() : ResultBody.failed();
    }

    @ApiOperation("1.3.获取文件分隔符")
    @GetMapping("/separator")
    public ResultBody separator() {
        return ResultBody.ok().data(File.separator);
    }

    @ApiOperation("1.4.获取上级目录")
    @GetMapping("/parent")
    @ApiImplicitParam(name = "file", value = "文件路径", defaultValue = "/Users/xx/code", example = "/Users/xx/code", paramType = "query", required = true, dataType = "String")
    public ResultBody parent(@ApiIgnore @RequestParam String file) {
        String parent = new File(file).getParent();
        if(parent != null){
            return ls(new File(file).getParent());
        }else{
            return ResultBody.failed();
        }
    }

    @ApiOperation("1.5.上传文件")
    @PostMapping(value = "/upload", produces = "application/json;charset=UTF-8")
    public ResultBody upload(@RequestParam("file") MultipartFile file,
                              @RequestParam("path") String path) {
        String saveFile = path + File.separator + file.getOriginalFilename();
        try {
            FileUtil.writeFromStream(file.getInputStream(), saveFile);
        } catch (IOException e) {
            return ResultBody.failed();
        }
        return ls(path);
    }
}
